package com.vxdata.common.log;

import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;

/**
 * 自定义的日志格式化类，继承自 PatternLayout。
 * 该类用于在日志输出前清理消息中的转义字符和 URL 编码。
 * 需要在 logback.xml 中添加配置:
 * <layout class="com.vxdata.adr.common.SanitizePatternLayout">
 * <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
 * </layout>
 *
 * 如果日志级别是error, 不会打印, 不会走doLayout方法
 */
public class SanitizePatternLayout extends PatternLayout {

    /**
     * 格式化日志事件。
     * 该方法重写了 PatternLayout 的 doLayout 方法，用于对日志消息进行清理。
     *
     * @param event 日志事件
     * @return 清理后的日志消息
     */
    @Override
    public String doLayout(ILoggingEvent event) {
        // 获取原始日志消息
        String originalMessage = event.getFormattedMessage();
        // 对原始日志消息进行清理
        String sanitizedMessage = sanitizeMessage(originalMessage);

        // 打印原始消息和清理后的消息到控制台（仅用于调试）
//        System.out.println("原始消息: " + originalMessage);
//        System.out.println("新的消息: " + sanitizedMessage);

        // 调用父类的 doLayout 方法来格式化日志事件，并用清理后的消息替换原始消息
        String formattedMessage = super.doLayout(event).replace(originalMessage, sanitizedMessage);
        return formattedMessage;
    }

    /**
     * 清理日志消息中的转义字符和 URL 编码。
     * 该方法通过正则表达式移除控制字符和 URL 编码（如 %0a, %20）。
     *
     * @param message 原始日志消息
     * @return 清理后的日志消息
     */
    private String sanitizeMessage(String message) {
        return message.replaceAll("\\p{Cntrl}", "") // 移除所有控制字符（如换行符、回车符等）
                .replaceAll("%[0-9a-fA-F]{2}", ""); // 移除 URL 编码（如 %0a, %20）
    }
}
